<script lang="tsx">
import { type ExtractPropTypes, computed, defineComponent } from 'vue'

const TitleProps = {
  columns: {
    type: Array,
    default: () => []
  },
  titleList: {
    type: Array,
    default: () => []
  },
  maxDeep: {
    type: Number,
    default: 1
  },
  showBorder: {
    type: Boolean,
    default: false
  },
  borderBottom: {
    type: Boolean,
    default: true
  },
  isHeaderFixed: {
    type: Boolean,
    default: false
  },
  headerFixedTopValue: {
    type: [Number, String],
    default: 88
  },
  rowWidth: {
    type: Number,
    default: 375
  },
  headerHeight: {
    type: [Number, String],
    default: 42
  },
  showTitleTopBorder: {
    type: Boolean,
    default: false
  },
  headerBackground: {
    type: String,
    default: ''
  },
  fixedCol: {
    type: String,
    default: 'center'
  },
  htmlFontSize: {
    type: [Number, String],
    default: 100
  },
  fixedWidthDefault: {
    type: [Number, String],
    default: 70
  }
}

export type TitleProps = ExtractPropTypes<typeof TitleProps>

function changeSort(obj: { sort?: string }, emit: (event: string, payload: any) => void) {
  // 切换排序
  if (!obj?.sort) {
    return false
  }
  emit('changeSortHandler', { ...obj })
}

function justifyContent(item: string = 'left'): string {
  const alignMap: Record<string, string> = {
    left: 'flex-start',
    center: 'center',
    right: 'flex-end'
  }
  return alignMap[item] || alignMap.left
}

export default defineComponent({
  name: 'TableTitle',
  props: TitleProps,
  setup(props, { slots, attrs, emit }) {
    // 单元格样式
    const tableTitleCell = (item: any) => {
      let content = []
      const slotName = slots[item.slotHeader]
      const isSlot = typeof slotName === 'function'
      if (isSlot) {
        content.push(slotName({ titleItem: item }))
      } else {
        content.push(
          <span v-html={item.title} class="table-title-cell-span"></span>
        )
      }
      return (
        <div
          class={['table-title-cell', { 'table-title-cell-sort': 'sort' in item && !isSlot }]}
          style={{ justifyContent: justifyContent(item.align) }}
        >
          {content}
        </div>
      )
    }

    // th标签样式
    const thDom = (col: any[]) => {
      return col.map((item, index) => (
        <th
          key={index}
          rowspan={item.rowSpan}
          colspan={item.colSpan}
          class={[
            { 'show-border': props.showBorder },
            { 'border-bottom': props.borderBottom },
            { 'column-last': item.isLastCol }
          ]}
          style={{
            zIndex: item.fixed ? 60 : undefined,
            textAlign: item.align || (item.hasChildren ? 'center' : 'left'),
            background: props.headerBackground
          }}
          onClick={(e) => changeSort(item, emit)}
        >
          {tableTitleCell(item)}
        </th>
      ))
    }

    // thead标签样式
    const theadDom = () => (
      <thead class={[{ 'title-top-border': props.showBorder }, 'table-thead']}>
        {props.titleList.map((item, index) => (
          <tr key={index} class="table-thead-th" style={{ height: `${props.headerHeight}px` }}>
            {thDom(item)}
          </tr>
        ))}
      </thead>
    )

    // col标签样式,用来控制列的宽度
    const colgroups = () => (
      <colgroup>
        {props.columns.map((item, index) => {
          let colWidth = 100
          try {
            colWidth = (+item.width || props.fixedWidthDefault).toFixed(2)
          } catch (e) {}
          return (
            <col
              key={index}
              style={{
                width: props.fixedCol === 'center' && item.widthAuto ? 'auto' : `${colWidth}px`
              }}
            ></col>
          )
        })}
      </colgroup>
    )

    return () => (
      <div
        class={[
          'table-title',
          { 'table-title-left': props.fixedCol === 'left' },
          { 'table-title-center': props.fixedCol === 'center' },
          { 'fixed-top': props.isHeaderFixed }
        ]}
        style={{ top: props.showBorder ? `${props.headerFixedTopValue}px` : '' }}
      >
        <table style={{ width: `${props.rowWidth}px` }}>{[colgroups(), theadDom()]}</table>
      </div>
    )
  }
})
</script>

<style lang="less" scoped>
.table-title {
  max-width: 100%;
  &.fixed-top {
    position: sticky;
    left: 0;
    top: 88px;
    z-index: 70;
  }
  table {
    min-width: 100%;
    table-layout: fixed;
    background-color: #fff;
    .table-thead {
      position: relative;
    }
    th {
      background-color: #fff;
      position: relative;
      &.border-bottom::after {
        content: '';
        width: 100%;
        height: 1px;
        background-color: #dcdee0;
        position: absolute;
        bottom: 0;
        left: 0;
        transform: scaleY(0.5);
      }
    }
  }
}
</style>